home *** CD-ROM | disk | FTP | other *** search
- /*+
- * File: SARCH
- * Description:
- * This is a simple archive utility program.
- * Sarch tries to only rely on the C stdio library functions.
- * When transferring multiple files between two machines that only have a
- * single file transfer utility, sarch becomes handy. Multiple files
- * are converted to a sinle file on one end, transfered to the other
- * machine and extracted to the original files at the destination.
- * System dependent features are very few, keeping it simple
- * and portable. Efficiency is sacrificed for portability.
- * CRCs are computed when updateing and when extracting.
- *
- * Usage:
- * sarch -{m,u,x,a,t} archname file1 .. filen
- * -m Print file names within the archive.
- * -u Add or update files to the archive.
- * -x Extract files from archive.
- * -a Extract all files from the rachive.
- * -t PCDOS related. When extracting, test mode is set.
- *
- *
- * Author: Mohsen Banan.
- *
- * This program is public domain software, no warranty intended or
- * implied.
- * General permission to copy or modify, but not for profit, is
- * hereby granted.
- *
- *
- * Functions:
- *
- * Sarch relies on the archive manipulating functions:
- * ar_open(), ar_close()
- * ar_get(), ar_put(), ar_seek().
- * ar_get, gets (extracts) a file from the archive.
- * ar_put, puts (adds) a file to the archive.
- *
- *
- * Audit Trail: $Log: sarch.c,v $
- * Revision 1.1 85/08/28 08:38:52 mohsen
- * original posting to the net
- *
- * Revision 1.1 85/08/13 17:30:27 mohsen
- * Initial revision
- *
- * Revision 1.2 85/04/25 10:27:22 mohsen
- * In this version sarch was working fine with the -a and -u options.
- *
- * Revision 1.1 85/04/19 16:24:43 mohsen
- * Initial revision
- *
- *
- -*/
-
- #ifdef RCS_VER
- static char *rcs = "$Header: sarch.c,v 1.1 85/08/28 08:38:52 mohsen Exp $";
- #endif
-
- /* #includes */
- #include "mbstd.h"
- #include <stdio.h>
- #include <fcntl.h>
- #ifdef unix
- #include "msc3.h"
- #endif
-
- /* #defines */
- #define AR_BSTR "<archive>"
- #define AR_ESTR "<archive>"
-
- /*
- * All fileds of ARCH_HDR are strings (0 terminated),
- * All fields are left justified.
- */
- typedef struct {
- CHAR ar_bstr[16]; /* begining archive string */
- CHAR fname[16];
- CHAR fsize[8];
- CHAR fcrc[8];
- CHAR ar_estr[16]; /* end archive string */
- } ARCH_HDR;
-
- /* external variables */
-
- /* referenced external function declarations */
- EXTERN USHORT fcrc16();
-
- /* internal function declarations */
- PUBLIC VOID sarch();
- PUBLIC FILE * ar_open();
- PUBLIC INT ar_close();
- PUBLIC SUCC_FAIL ar_put();
- PUBLIC SUCC_FAIL ar_get();
- PUBLIC SUCC_FAIL ar_seek();
- LOCAL VOID wr_hdr();
- LOCAL SUCC_FAIL rd_hdr();
- LOCAL VOID fld2str();
- PUBLIC VOID cpf();
- PUBLIC VOID cant_open();
- STATIC VOID usage();
-
- /* global variables */
-
- /* static variables */
- STATIC CHAR * prog_name;
- STATIC ARCH_HDR gw_hdr; /* generic write archive header */
- STATIC ARCH_HDR gr_hdr; /* generic read archive header */
- STATIC BOOL txt_mode_flag;
-
- INT
- main (argc, argv)
- INT argc;
- CHAR * argv[];
- {
- sarch(argc, argv);
- }
-
-
- /*<
- * Function:SARCH
- * Description:
- * Parses the command line and relies on archive manipulating functions to do
- * what it should do.
- *
- * Returns:
- * VOID
- *
- >*/
- PUBLIC VOID
- sarch (argc,argv)
- INT argc;
- CHAR * argv[];
- {
- FILE * ar_fp;
-
- BOOL add_flag;
- BOOL xt_flag;
- BOOL xt_all_flag;
-
- INT i;
-
- add_flag = xt_flag = xt_all_flag = txt_mode_flag = FALSE;
- ar_fp = stdout;
- prog_name = argv[0];
-
- sprintf (gw_hdr.ar_bstr, "%-15s", AR_BSTR);
- sprintf (gw_hdr.ar_estr, "%-15s", AR_ESTR);
-
- for (i=1; i<argc; ++i) {
- if (*argv[i] == '-') {
- /* To handle concatenated switches */
- INT j;
- j=i;
- while (*(++argv[j])) {
- switch (*argv[j]) {
- case 'u':
- case 'U':
- /*
- * add or update a file to the archive
- */
- if (!(ar_fp = ar_open (argv[++i], "w"))) {
- cant_open(prog_name, argv[i]);
- exit (1);
- }
- add_flag = TRUE;
- break;
- case 'x':
- case 'X':
- /*
- * Extract a file from the archive.
- */
- if (!(ar_fp = ar_open (argv[++i], "r"))) {
- cant_open(prog_name,argv[i]);
- exit(1);
- }
- xt_flag = TRUE;
- break;
- case 'a':
- case 'A':
- /*
- * Extract all files with in this archive
- */
- if (!(ar_fp = ar_open (argv[i+1], "r"))) {
- cant_open(prog_name,argv[i]);
- exit(1);
- }
- xt_all_flag = TRUE;
- break;
- case 't':
- case 'T':
- txt_mode_flag = TRUE;
- break;
- default:
- usage();
- exit(1);
- } /* switch (*argv[j]) */
- } /* while (*(++argv[j])) */
- } /* if '-' */
- else if (ar_fp == stdout) {
- /*
- * This is equivalent to "-u" option, ar_fp is stdout.
- */
- add_flag = TRUE;
- }
- else {
- /*
- * the rest of command line arguments are assumed to be file names.
- */
- if (add_flag) {
- ar_put (ar_fp, &gw_hdr,argv[i]);
- }
- else if (xt_flag) {
- ar_seek (ar_fp, &gr_hdr, argv[i]);
- ar_get (ar_fp,&gr_hdr);
- }
- else if (xt_all_flag) {
- while ( ar_seek (ar_fp, &gr_hdr,(CHAR *) NULL) == SUCCESS ) {
- ar_get (ar_fp, &gr_hdr);
- }
- }
- else {
- /*
- OOPS();
- */
- }
- }
- } /* for i<argc */
- ar_close (ar_fp);
- exit (0);
- }
-
-
- /*<
- * Function:ar_open
- * Description:
- * Opens an archive directory.
- *
- * Returns:
- * Same as fopen.
- *
- *
- >*/
- PUBLIC FILE *
- ar_open(path, type)
- CHAR * path;
- CHAR * type;
- {
- FILE * fp;
- if ( fp=fopen(path,type) ) {
- setmode (fileno(fp), O_BINARY);
- }
- return (fp);
- }
-
-
-
- /*<
- * Function:ar_close
- * Description:
- * Closes an archive file
- *
- * Returns:
- * same as fclose.
- *
- >*/
- PUBLIC INT
- ar_close(ar_fp)
- FILE * ar_fp;
- {
- return (fclose(ar_fp));
- }
-
-
-
- /*<
- * Function: ar_put
- * Description:
- * Puts the contents of the file specified in "path" into the archive.
- * Archive header is written prior to copying the file.
- *
- * Returns:
- * SUCCESS:
- * No problems.
- * FAIL:
- * Couldn't open the file that it is supposed to put it in.
- *
- >*/
- PUBLIC SUCC_FAIL
- ar_put(ar_fp, p_ar_hdr, path)
- FILE * ar_fp;
- ARCH_HDR * p_ar_hdr;
- CHAR * path;
- {
- FILE * fp;
- SUCC_FAIL retval;
- LONG fsize;
- USHORT crc;
-
- retval = SUCCESS;
- if (!(fp = fopen(path, "r"))) {
- cant_open (prog_name, path);
- retval = FAIL;
- } else {
- setmode (fileno(fp), O_BINARY);
- crc = fcrc16(fp, (USHORT)0, &fsize);
- rewind(fp);
- sprintf (p_ar_hdr->fsize, "%-7ld", fsize);
- sprintf (p_ar_hdr->fcrc, "%-7x", (int)crc);
- sprintf (p_ar_hdr->fname, "%-15s", path);
- wr_hdr(ar_fp, p_ar_hdr);
- cpf (fp, ar_fp, fsize);
- fclose(fp);
- }
- return (retval);
- }
-
-
- /*<
- * Function:ar_get
- * Description:
- * Gets (extracts) the contents of a file from the archive.
- * and stores it in the file specified in the archive header.
- * ar_get is to be invoked after the execution of ar_seek.
- *
- * Returns:
- * SUCCESS:
- * Every thing went fine.
- * FAIL:
- * Couldn't open the file.
- *
- *
- >*/
- PUBLIC SUCC_FAIL
- ar_get(ar_fp, p_ar_hdr)
- FILE * ar_fp;
- ARCH_HDR * p_ar_hdr;
- {
- FILE * fp;
- SUCC_FAIL retval;
- LONG fsize;
- LONG nfsize;
- USHORT crc;
- USHORT ncrc;
- UINT int_crc;
-
- retval = SUCCESS;
-
- if (!(fp = fopen(p_ar_hdr->fname, "w+"))) {
- cant_open (prog_name, p_ar_hdr->fname);
- retval = FAIL;
- } else {
- setmode(fileno(fp), O_BINARY);
- sscanf (p_ar_hdr->fsize, "%ld", &fsize);
- cpf((FILE *)ar_fp, fp, fsize);
- rewind(fp);
- ncrc = fcrc16(fp, (USHORT)0, &nfsize);
- sscanf (p_ar_hdr->fcrc, "%x", &int_crc);
- crc = int_crc;
- if ( (crc != ncrc) || (fsize != nfsize) ) {
- retval = FAIL;
- fprintf(stderr, "%s: Problem extacting %s size=%ld, crc=%x\n",
- prog_name, p_ar_hdr->fname, fsize, (int)crc);
- fprintf(stderr, "%s: Problem extacting %s nsize=%ld, ncrc=%x\n",
- prog_name, p_ar_hdr->fname, nfsize, (int)ncrc);
- }
- fclose(fp);
- }
- return (retval);
- }
-
-
- /*<
- * Function: ar_seek
- * Description:
- * If path is NULL, the current archive header is read into
- * p_ar_hdr.
- * Otherwise, the archive is searched for the specified file
- * name addressed by path.
- *
- * Returns:
- * SUCCESS if found.
- * FAIL if not found, or problem.
- *
- *
- >*/
- LOCAL SUCC_FAIL
- ar_seek(ar_fp, p_ar_hdr, path)
- FILE * ar_fp;
- ARCH_HDR * p_ar_hdr;
- CHAR * path;
- {
- SUCC_FAIL retval;
-
- retval = SUCCESS;
- if (!path ) {
- /* then get it any way */
- retval = rd_hdr(ar_fp, p_ar_hdr);
- } else {
-
- }
- return (retval);
- }
-
-
- /*<
- * Function:wr_hdr
- * Description:
- * Copy the contents of ARCH_HDR to the archive header.
- * See rd_hdr for the file archive header picture.
- *
- * Returns:
- * VOID
- *
- >*/
- LOCAL VOID
- wr_hdr (ar_fp, p_ar_hdr)
- FILE * ar_fp;
- ARCH_HDR * p_ar_hdr;
- {
- fprintf (ar_fp , "%-15s", p_ar_hdr->ar_bstr);
- fprintf (ar_fp , "%-15s", p_ar_hdr->fname);
- fprintf (ar_fp , "%-7s", p_ar_hdr->fsize);
- fprintf (ar_fp , "%-7s", p_ar_hdr->fcrc);
- fprintf (ar_fp , "%-15s", p_ar_hdr->ar_estr);
- putc ('\n',ar_fp);
- }
-
-
- /*<
- * Function:rd_hdr
- * Description:
- * Reads a header and fills up the ARCH_HDR.
- *
- 0 1 2 3 4 5 6
- 0123456789012345678901234567890123456789012345678901234567890
- 123456789012345678901234567890123456789012345678901234567890
- b b b b b
- ar_bstr fname fsize fcrc ar_estr
- *
- * Returns:
- * SUCCESS:
- * FAIL:
- * archive header is bad.
- *
- *
- >*/
- LOCAL SUCC_FAIL
- rd_hdr (ar_fp, p_ar_hdr)
- FILE * ar_fp;
- ARCH_HDR * p_ar_hdr;
- {
- SUCC_FAIL retval;
- CHAR hdr_line[256];
- INT i;
-
- retval = SUCCESS;
- if (!fgets (hdr_line, 255,ar_fp)) {
- retval = FAIL;
- } else {
- fld2str (&hdr_line[0], p_ar_hdr->ar_bstr, 15);
-
- for (i=15; i<30; ++i) {
- if ( hdr_line[i] != ' ') {
- p_ar_hdr->fname[i-15] = hdr_line[i];
- } else {
- break;
- }
- }
- p_ar_hdr->fname[i-15] = '\0';
-
- fld2str (&hdr_line[30], p_ar_hdr->fsize, 7);
- fld2str (&hdr_line[37], p_ar_hdr->fcrc, 7);
- fld2str (&hdr_line[43], p_ar_hdr->ar_estr, 15);
- }
- return (retval);
-
- }
-
- LOCAL VOID
- fld2str ( fld, str, size)
- CHAR * fld;
- CHAR * str;
- INT size;
- {
- INT i;
- for (i=0; i<size; ++i) {
- *str++ = *fld++;
- }
- *str = '\0';
- }
-
-
-
- /*<
- * Function:cpf
- * Description:
- * Copy the first <fsize> bytes of <src_fp> to <dst_fp>
- *
- * Returns:
- * VOID
- *
- * Side Effects:
- * Both src_fp and dst_fp characters pointers are moved.
- *
- >*/
- LOCAL VOID
- cpf (src_fp, dst_fp, fsize)
- FILE * src_fp;
- FILE * dst_fp;
- LONG fsize;
- {
- LONG i;
- for (i=0; i<fsize; ++i) {
- putc(getc(src_fp), dst_fp);
- }
- }
-
-
- PUBLIC VOID
- cant_open (prog_name,filename)
- CHAR * prog_name;
- CHAR * filename;
- {
- fprintf (stderr, "%s :can not open %s \n", prog_name, filename);
- }
-
- STATIC VOID
- usage ()
- {
- fprintf (stderr, "Usage: %s [-u] [-x] <filename> \n", prog_name);
- }
-
-